using System;
using System.Collections.Generic;
using System.Text;


using System.Xml.XPath;
using System.Xml.Xsl;


namespace BadHabit.Factory.Reports {


    /// <summary>
    /// Represents a generic report class. This is an abstract class.
    /// </summary>
    public abstract class Report {

        public string ProjectUId { get; set; }
        public string ProjectCategory { get; set; }
       
        
        protected Factory factory;

        public Report(Factory factory) {
            this.factory = factory;
        }

        /// <summary>
        /// The template type name. Should be overriden.
        /// </summary>
        public abstract string TemplateTypeName {
            get;
        }
       
        /// <summary>
        /// Adjusts the dastaset for XPS render.
        /// </summary>
        /// <param name="report">Report dataset</param>
        /// <returns>The adjusted dataset</returns>
        public virtual System.Data.DataSet AdjustDataSet(System.Data.DataSet report) {
            report.Namespace = "";
            report.EnforceConstraints = false;

            if (!report.Tables.Contains("General")) {
                report.Tables.Add("General");
            }
            
            report.Tables["General"].Columns.Add("TodayString", typeof(string));
            report.Tables["General"].Columns.Add("ServerURL", typeof(string));
            report.Tables["General"].Rows.Add(new object[] { DateTime.Now.ToLongDateString() + ", " + DateTime.Now.ToLongTimeString(), Factory.ServerUrl } );

            return report;
        }

        /// <summary>
        /// Adjusts the dataset for XPS render.
        /// </summary>
        /// <param name="projectUId">The projectUId</param>
        /// <returns>The adjusted dataset</returns>
        public virtual System.Data.DataSet CreateDataSet() {
            return new System.Data.DataSet();
        }

        /// <summary>
        /// Retrives the template list.
        /// </summary>        
        public String[] RetriveTemplateList() {
            string path = Factory.ServerPath + ".\\App_Data\\ReportTemplates\\" + TemplateTypeName + "\\";
            String[] list = System.IO.Directory.GetFiles(path, "*.xslt");
            List<string> templateList = new List<string>();
            for (int i = 0; i < list.Length; i++) {
                string template = list[i].Substring(list[i].LastIndexOf("\\") + 1);
                if (!template.StartsWith("_"))
                    templateList.Add(template);
            }
            return templateList.ToArray();
        }
        
        

        public string GenerateFlowDocumentXAML(string templateName) {
            System.Data.DataSet report = CreateDataSet();
            return GenerateFlowDocumentXAML(report, templateName);
        }


        public string GenerateFlowDocumentXAML(System.Data.DataSet report, string templateName) {

            // Do this in order to avoid to change the original dataset
            System.Data.DataSet myReport = report.Copy();            

            // adjust the report
            myReport = AdjustDataSet(myReport);

            // create the XPS file            
            string contextUri = Factory.ServerPath + ".\\";
            string xsltFileName = Factory.ServerPath + ".\\App_Data\\ReportTemplates\\" + TemplateTypeName + "\\" + templateName;

            // load the Xslt             
            XslCompiledTransform xslTrans = new XslCompiledTransform();
            xslTrans.Load(xsltFileName);

            // create the output stream           
            StringBuilder xaml = new StringBuilder();
            System.IO.StringWriter stringWriter = new System.IO.StringWriter(xaml);
            
            // do the actual transform of Xml            
            xslTrans.Transform(new XPathDocument(new System.IO.StringReader(myReport.GetXml())), null, stringWriter);

            return xaml.ToString();            
            
        }

        

        /// <summary>
        /// Helper function for short dates.
        /// </summary>
        /// <param name="d">Any date</param>
        /// <returns>The Month and the day of the date</returns>
        public string MiniShortDateString(DateTime d) {
            string m = d.ToString("MMMM").Substring(0, 3);
            return d.Day + "-" + m;
        }

       
    }
}
